package tt.dz.egobus.servicemanager.bean;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import tt.dz.egobus.servicemanager.service.*;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author Anson
 * @date 17-8-29
 * @name
 * @since 1.0.7
 */
public abstract class AbstractGrabApplicationContext implements ApplicationContextAware {

    protected ApplicationContext applicationContext;


    private Map<String, AtomicReference<?>> containerMap = new ConcurrentHashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext application) {
        this.applicationContext = application;
    }

    /**
     * 获取抢单GrabRedisBusinessWorkCacheService服务
     *
     * @return
     */
    protected GrabRedisBusinessWorkCacheService getGrabRedisBusinessWorkCacheService() {
        return this.getReferenceObject(
                "grabRedisBusinessWorkCacheServiceImpl", GrabRedisBusinessWorkCacheService.class);
    }

    /**
     * 获取抢单DriverRegisterBusRelativeService服务
     *
     * @return
     */
    protected GrabDriverRegisterBusRelativeService getDriverRegisterBusRelativeServiceReference() {
        return this.getReferenceObject(
                "grabDriverRegisterBusRelativeServiceImpl", GrabDriverRegisterBusRelativeService.class);
    }

    /**
     * 获取抢单BusinessServiceService服务
     *
     * @return
     */
    protected BusinessServiceService getBusinessServiceServiceReference() {
        return this.getReferenceObject(
                "businessServiceServiceImpl", BusinessServiceService.class);
    }

    /**
     * 获取抢单GrabBusinessCacheService服务
     *
     * @return
     */
    protected GrabBusinessCacheService getBusinessCacheServiceReference() {
        return this.getReferenceObject(
                "grabRedisBusinessCacheServiceImpl", GrabBusinessCacheService.class);
    }

    /**
     * 获取抢单BusinessServiceInfoService服务
     *
     * @return
     */
    protected BusinessServiceInfoService getBusinessServiceInfoServiceReference() {
        return this.getReferenceObject(
                "businessServiceInfoServiceImpl", BusinessServiceInfoService.class);
    }

    /**
     * @param beanName
     * @param clazz
     * @author Anson
     * @date 17-8-29
     * @name
     * @since 1.0.7
     */
    private <T> T getReferenceObject(String beanName, Class<T> clazz) {
        AtomicReference reference = containerMap.get(beanName);
        if (reference == null) {
            reference = new AtomicReference();
        }
        T t = (T) reference.get();
        if (t == null) {
            t = this.applicationContext.getBean(beanName, clazz);
            reference.set(t);
            containerMap.putIfAbsent(beanName, reference);
        }
        return t;
    }

}
